package com.itcam.tingshu.album.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itcam.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.itcam.tingshu.album.mapper.AlbumInfoMapper;
import com.itcam.tingshu.album.mapper.AlbumStatMapper;
import com.itcam.tingshu.album.mapper.TrackInfoMapper;
import com.itcam.tingshu.album.service.AlbumAttributeValueService;
import com.itcam.tingshu.album.service.AlbumInfoService;
import com.itcam.tingshu.album.service.TrackInfoService;
import com.itcam.tingshu.common.cache.ItcamCache;
import com.itcam.tingshu.common.constant.KafkaConstant;
import com.itcam.tingshu.common.constant.SystemConstant;
import com.itcam.tingshu.common.service.KafkaService;
import com.itcam.tingshu.model.album.AlbumAttributeValue;
import com.itcam.tingshu.model.album.AlbumInfo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itcam.tingshu.model.album.AlbumStat;
import com.itcam.tingshu.query.album.AlbumInfoQuery;
import com.itcam.tingshu.vo.album.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Autowired
    private AlbumAttributeValueService albumAttributeValueService;

    @Autowired
    private KafkaService kafkaService;

    @Autowired
    private TrackInfoMapper trackInfoMapper;


    /**
     * 保存专辑
     * @param albumInfoVo
     * @param userId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo, long userId) {

        try {
            // album_info

            // 创建专辑对象
            AlbumInfo albumInfo = new AlbumInfo();
            // 进行属性拷贝
            BeanUtils.copyProperties(albumInfoVo, albumInfo);
            // 设置初始化状态为审核通过
            albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
            // 设置前五集为免费试看
            if (SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfo.getPayType())) {
                // 只要收费，就设置前五集为免费试听集数
                albumInfo.setTracksForFree(5);
            }
            // 当执行插入完成之后，获取到专辑id
            // 在实体类id属性上：@Table(type=IdType.AUTO)——表示插入完成之后能否自动获取到主键自增的id
            albumInfoMapper.insert(albumInfo);

            // album_attribute_value

            List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();

            if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
                // 声明一个集合
                // List<AlbumAttributeValue> albumAttributeValueList = new ArrayList<>();
                // 循环遍历这个集合保存数据
                // for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
                //     // 创建一个专辑对应的属性与属性值对象
                //     AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                //     albumAttributeValue.setAlbumId(albumInfo.getId());
                //     albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
                //     albumAttributeValue.setValueId(albumAttributeValue.getValueId());
                //     // albumAttributeValueMapper.insert(albumAttributeValue);
                //     albumAttributeValueList.add(albumAttributeValue);
                // }
            /*
                todo:拿着集合里面的每一个元素，取出集合的元素并且给一个对象赋值，同时把这个对象放入新的集合里，这就是stream流
                    循环遍历集合中的元素，把元素的属性取出来，赋值给一个对象，并且把这个对象放在新的集合里面
             */
                List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
                    AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                    albumAttributeValue.setAlbumId(albumInfo.getId());
                    albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
                    albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
                    return albumAttributeValue;
                }).collect(Collectors.toList());


                // 批量保存：albumAttributeValueMapper album_attribute_value
                // 利用mybatis-plus中IService ServiceImpl这个类处理
                albumAttributeValueService.saveBatch(albumAttributeValueList);
            }

            // album_stat

            this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_PLAY);
            this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_SUBSCRIBE);
            this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_BROWSE);
            this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_COMMENT);

            // 发送上架消息
            if ("1".equals(albumInfo.getIsOpen())) {
                kafkaService.sendMsg(KafkaConstant.QUEUE_ALBUM_UPPER, String.valueOf(albumInfo.getId()));
            }
        } catch (BeansException e) {
            log.error("保存专辑失败");
            e.printStackTrace();
        }
    }

    /**
     * 获取用户专辑分页列表
     * @param albumListVoIpage
     * @param albumInfoQuery
     * @return
     */
    @Override
    public IPage<AlbumListVo> getUserAlbumPage(Page<AlbumListVo> albumListVoIpage, AlbumInfoQuery albumInfoQuery) {
        //  根据业务分析：需要 album_info album_stat
        return albumInfoMapper.selectUserAlbumPage(albumListVoIpage, albumInfoQuery);
    }

    /**
     * 根据专辑Id删除专辑
     * @param albumId
     */
    @Override
    public void removeAlbumInfo(Long albumId) {
        /*
            album_attribute_value
            album_info
            album_stat
        */
        //  删除：
        //      逻辑删除 update album_info set is_deleted = ? where id = ?
        //      物理删除 delete from album_info where album_id = ?
        albumInfoMapper.deleteById(albumId); // 逻辑删除

        //  delete from album_stat where album_id = ?;
        albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));

        //  delete from album_attribute_value where album_id = ?;
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));

        // 根据专辑Id删除album_info album_attribute_value album_stat
        // albumInfoMapper.deleteAlbumInfo(albumId);
        // albumStatMapper.deleteAlbumStat(albumId);
        // albumAttributeValueService.deleteAlbumAttributeValue(albumId);

    }

    /**
     * 根据专辑Id回显专辑数据
     * @param albumId
     * @return
     */
    @Override
    public AlbumInfo getAlbumInfoById(Long albumId) {
        // 先获取到专辑信息表数据 album_info
        // select * from album_info where album_id=? and is_deleted = 0
        AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
        // 获取到专辑属性与属性值数据集合
        if (albumId != null) {
            // 想办法获取到属性与属性值集合数据
            // 根据album_id查询album_attribute_value集合
            // select * from album_attribute_value where album_id = ？
            List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueMapper.selectList(new LambdaQueryWrapper<AlbumAttributeValue>()
                    .eq(AlbumAttributeValue::getAlbumId, albumId));
            albumInfo.setAlbumAttributeValueVoList(albumAttributeValueList);
        }
        // 返回对象数据
        return albumInfo;
    }

    /**
     * 根据专辑Id修改专辑对象
     * @param albumId
     * @param albumInfoVo
     */
    @Override
    public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
        // 修改简介相当于修改 album_info
        // 第一个参数表示要修改的内容，第二个参数表示修改的条件
        // albumInfoMapper.update();
        // 第一个参数表示修改的内容+条件{主键+id}
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        albumInfo.setId(albumId);
        albumInfoMapper.updateById(albumInfo);

        // 修改标签相当于修改 album_attribute_value
        // 先删除，再新增
        // 物理删除：delete from album_attribute_value where album_id = ?;
        // 逻辑删除：update album_attribute_value set is_deleted = 1 where album_id=?;
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>()
                .eq(AlbumAttributeValue::getAlbumId, albumId));

        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();

        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueVoList.stream().map(albumAttributeValueVo -> {
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                albumAttributeValue.setAlbumId(albumInfo.getId());
                albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
                albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
                return albumAttributeValue;
            }).collect(Collectors.toList());


            // 批量保存：albumAttributeValueMapper album_attribute_value
            // 利用mybatis-plus中IService ServiceImpl这个类处理
            albumAttributeValueService.saveBatch(albumAttributeValueList);
        }

        if ("1".equals(albumInfo.getIsOpen())) {
            // 上架
            kafkaService.sendMsg(KafkaConstant.QUEUE_ALBUM_UPPER, albumId.toString());
        } else {
            // 下架
            kafkaService.sendMsg(KafkaConstant.QUEUE_ALBUM_LOWER, albumId.toString());
        }
    }

    /**
     * 获取当前用户全部专辑列表
     * @param userId
     * @return
     */
    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        // 根据用户Id查询专辑列表
        // List<AlbumInfo> albumInfos = albumInfoMapper.selectList(new LambdaQueryWrapper<AlbumInfo>()
        //         .eq(AlbumInfo::getUserId, userId));
        // select id,album_title from album_info where user_id=?order by id desc limit 0,20; // limit 0,20;代表可以变得，可以随便看页数
        // select id,album_title from album_info where user_id=?order by id desc limit 20; // limit 20; 表示只看一页
        // Page<AlbumInfo> albumInfoPage = new Page<>(1, 20);
        // 设置查询条件
        LambdaQueryWrapper<AlbumInfo> queryWrapper = new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getUserId, userId)
                .select(AlbumInfo::getId, AlbumInfo::getAlbumTitle)
                .orderByDesc(AlbumInfo::getId)
                .last("limit 20");
        // Page<AlbumInfo> selectPage = albumInfoMapper.selectPage(albumInfoPage, queryWrapper);
        // 返回查询记录
        return albumInfoMapper.selectList(queryWrapper);
    }

    /**
     * 根据专辑Id查询专辑属性与属性值集合
     * @param albumId
     * @return
     */
    @Override
    public List<AlbumAttributeValue> findAlbumAttributeValue(Long albumId) {
        /*
            select
                attribute_id,
                value_id
            from album_attribute_value
            where album_id = ? and is_deleted = 0
        */
        // 使用mapper的时候默认给我们添加is_delete = 0;
        LambdaQueryWrapper<AlbumAttributeValue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlbumAttributeValue::getAlbumId, albumId);
        return albumAttributeValueMapper.selectList(queryWrapper);
    }

    /**
     * 根据专辑Id查询专辑统计信息
     * @param albumId
     * @return
     */
    @Override
    @ItcamCache(prefix = "stat:")
    public AlbumStatVo getAlbumStatVo(Long albumId) {
        return albumInfoMapper.selectAlbumStatVo(albumId);
    }

    /**
     * 专辑播放量更新
     * @param trackStatMqVo
     */
    @Override
    public void trackStatUpdate(TrackStatMqVo trackStatMqVo) {
        // 更新数据声音： update track_stat set stat_num = stat_num + 1 where track_id = 1 and stat_type = '0701';
        trackInfoMapper.trackStatUpdate(trackStatMqVo.getTrackId(),trackStatMqVo.getStatType(),trackStatMqVo.getCount());
        // 更新专辑
        if (SystemConstant.TRACK_STAT_PLAY.equals(trackStatMqVo.getStatType())) {
            // 调用更新专辑播放量方法
            albumInfoMapper.updateAlbumStat(
                    trackStatMqVo.getAlbumId(),
                    trackStatMqVo.getStatType(),
                    trackStatMqVo.getCount()
            );
        }
    }

    // --------------------------------------------------------------------------------
    public void saveAlbumStat(Long albumId, String statPlay) {
        //	创建统计对象
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(albumId);
        albumStat.setStatType(statPlay);
        albumStat.setStatNum(0);
        albumStatMapper.insert(albumStat);
    }
}
